<template>
  <div :class="animate" :style="{ height: height, width: width,overflowY:'hidden' }" :id="chartOption.bindingDiv" ref="text" @mouseenter="visible" @mouseleave="invisible">
      <!-- <div :style="normalItem"> -->
        <span v-for="(item, index) in boxes" 
            class="chooseCard" 
            :name="[isClicked(index) ? 'onSelected' : '']"
            :class="[isClicked(index) ? 'onSelected' : '']"
            :style="[isClicked(index) ? selectedStyle: normalStyle]"
            :id="item.key" 
            @click="chooseBox(index)"
            @mouseenter="pause" @mouseleave="start"
            :key="index"
        >
        {{ item.value }} 
        </span>
      <!-- </div> -->
  </div>
</template>

<script>
require("echarts/theme/macarons"); // echarts theme

import "../../animate/animate.css";

import { parseQueryString, fIsUrL } from "../../util/urlUtil";
import { chartApiBar,remoteChartApi,remoteTabApi,chartBIanalysis  } from "@/api/tool/datav/chartApi";
import { getFormsource } from '@/api/tool/datav/formsource'
import { websocketCommand } from "../../util/websocket.js";
const animationDuration = 6000;

export default {
  //mixins: [resize],
  props: {
    className: {
      type: String,
      default: "chart",
    },
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: String,
      default: "100%",
    },
    chartOption: {
      type: Object,
    },
    drawingList: {
      type: Array,
    },
  },
  data() {
    return {
      chart: null,
      boxes: this.chartOption.staticDataValue,
      clicked_list: [],
      max_clicked: this.chartOption.staticDataValue.length,
      paramStr: '',
      //dataOption: this.chartOption,
      timer:"",
      controlWsObj: null,
      controlWsFlag: false,
      controlWsTimer: "",
      wsObj: null,
      wsFlag: false,
      wsTimer: "",
      wsValue: null,
      animate: this.className,
      carouselTimer:"",//轮播定时器
      rotationIndex:0,//选中序号
    };
  },
  watch: {
    width() {},
    height() {},
    chartOption: {
      deep: true,
      handler(newVal) {
        this.setOptions(JSON.parse(JSON.stringify( newVal )));
      },
    },
    'chartOption.dur': {
      handler() {
        if(this.chartOption.checkType == "single"){
          this.setOptions(JSON.parse(JSON.stringify( this.chartOption )));
        }
      }
    },
    'chartOption.isRotation': {
      handler() {
        if(this.chartOption.checkType == "single"){
          this.setOptions(JSON.parse(JSON.stringify( this.chartOption )));
        }
      }
    },
    "chartOption.checkType": {
      handler(value) {
        //如果选择单选则把数据选中值清空
        if (value == "single") {
          this.clicked_list = []
        }
      }
    },
    "chartOption.isControl": {
      handler(value) {
        //切换数据源重新连接
        if (!value) {
          this.controlWsFlag = false;
          //每次切换数据源恢复原来动画
          this.animate = this.className;
        }
      }
    },
    "chartOption.controlKey": {
      handler(newValue, oldValue) {

        //删除键值断开连接
        if((oldValue !== undefined && oldValue != "" )&& (newValue == undefined || newValue == "")){
          this.controlWsFlag = false;
         
        }
        this.animate = this.className;
      }
    },
    "chartOption.dataSourceType": {
      handler(value) {
        if (value !== "websocket") {
          this.wsFlag = false;
          //每次切换数据源恢复原来动画
          this.animate = this.className;
        }
        if (value !== "url") {
          clearTimeout(this.timer);
        } 
      },
    },
    "chartOption.timeout": {
      handler() {
        this.chart = null;
        this.initChart();
      }
    },
    "chartOption.interfaceKey": {
      handler(newValue, oldValue) {
        //初始化不创建连接，改变接口地址重新创建
        if (oldValue !== undefined && oldValue != "") {
          this.wsValue = null;
          this.closeWs();
          this.createWs();
          this.animate = this.className;
        }
      }
    },
    wsFlag: {
      handler(value) {
        if (!value) {
          this.wsValue = null;
          this.closeWs();
        }
      }
    },
    controlWsFlag: {
      handler(value) {
        if (!value) {
          this.controlCloseWs();
        }
      }
    },
    className: {
      handler(value) {
        this.animate = value;
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });
  },
  beforeDestroy() {
    if (!this.chart) {
      return;
    }
    this.chart = null;
    clearTimeout(this.timer);
    clearTimeout(this.carouselTimer);
    if (this.controlWsFlag) {
      this.controlCloseWs();
    }
    if (this.wsFlag) {
      this.closeWs();
    }
  },
  computed: {
    selectId() {
      return "boxId" + this.customId;
    },
    normalItem() {
        this.width = '100%',
        this.height = '100%'
    },
    normalStyle() {
      const style = {
        // 字体
        color: this.chartOption.fontColor,
        fontSize: this.chartOption.fontSize + "px",
        fontWeight: this.chartOption.fontWeight,
        fontFamily: this.chartOption.fontFamily,
        letterSpacing: this.chartOption.letterSpacing + "px",

        // 内边距
        paddingLeft: this.chartOption.paddingLeftRight + "px",
        paddingRight: this.chartOption.paddingLeftRight + "px",
        paddingTop: this.chartOption.paddingTopBottom + "px",
        paddingBottom: this.chartOption.paddingTopBottom + "px",
        // 外边距
        marginLeft: this.chartOption.marginLeftRight + "px",
        marginRight: this.chartOption.marginLeftRight + "px",
        marginTop: this.chartOption.marginTopBottom + "px",
        marginBottom: this.chartOption.marginTopBottom + "px", 
        
      };
      //设置背景为图片
      if(this.chartOption.normalBGFlag == 'img'){
        // 边框
        style.borderWidth = "0px";
        style.borderColor = undefined;
        style.backgroundColor =  undefined;
        style.backgroundImage = `url(${this.chartOption.normalBGImage}) `;
        style.backgroundRepeat =  'no-repeat';
        style.backgroundSize = '100% 100%';

      }
      //设置背景为颜色
      else{
        // 边框
        style.borderWidth = this.chartOption.borderWidth + "px";
        style.borderColor = this.chartOption.borderColor;
        style.backgroundColor = this.chartOption.backgroundColor;
      }

      return style;
    },
    selectedStyle() {
      const style = {
        // 字体
        color: this.chartOption.selectedFontColor,
        fontSize: this.chartOption.selectedFontSize + "px",
        fontWeight: this.chartOption.selectedFontWeight,
        fontFamily: this.chartOption.selectedFontFamily,
        letterSpacing: this.chartOption.selectedLetterSpacing + "px",

        // 内边距
        paddingLeft: this.chartOption.paddingLeftRight + "px",
        paddingRight: this.chartOption.paddingLeftRight + "px",
        paddingTop: this.chartOption.paddingTopBottom + "px",
        paddingBottom: this.chartOption.paddingTopBottom + "px",
        // 外边距
        marginLeft: this.chartOption.marginLeftRight + "px",
        marginRight: this.chartOption.marginLeftRight + "px",
        marginTop: this.chartOption.marginTopBottom + "px",
        marginBottom: this.chartOption.marginTopBottom + "px",
      };

      //设置背景为图片
      if(this.chartOption.selectedBGFlag == 'img'){
        // 边框
        style.borderWidth = "0px";
        style.borderColor = undefined;
        style.backgroundColor =  undefined;
        style.backgroundImage = `url(${this.chartOption.selectedBGImage}) `;
        style.backgroundRepeat =  'no-repeat';
        style.backgroundSize = '100% 100%';

      }
      //设置背景为颜色
      else{
        // 边框
        style.borderWidth = this.chartOption.selectedBorderWidth + "px";
        style.borderColor = this.chartOption.selectedBorderColor;
        style.backgroundColor = this.chartOption.selectedBackgroundColor;
      }

      return style;
    },
    
  },
  methods: {
    initChart() {
     
      if (this.timer != "") {
        clearTimeout(this.timer);
      }
      if (this.carouselTimer != "") {
        clearTimeout(this.carouselTimer);
      }
      if (
        (this.chartOption.dataSourceType == "url" || this.chartOption.isStaticData == false) &&
        this.chartOption.timeout > 0
      ) {
        
        let timerTask = () => {
          this.setOptions(JSON.parse(JSON.stringify(this.chartOption)));
          
          this.timer = setTimeout(() => {
           
            timerTask();
          }, this.chartOption.timeout);
        };

        timerTask();
      }else{
        this.setOptions(JSON.parse(JSON.stringify( this.chartOption )));
      }
    },
    visible:function(){
      
      let style = document.getElementById(this.chartOption.bindingDiv).style;
      style.overflowY = 'auto'
      
      
    },
    invisible:function(){
      let style = document.getElementById(this.chartOption.bindingDiv).style;
      style.overflowY = 'hidden'
      
    },
    chooseBox(index) {
        //如果开启了远程控制
        if(this.chartOption.isSameRemote === true && this.chartOption.sameRemoteKey !== undefined && this.chartOption.sameRemoteKey !== ''){
          
          let remoteData = {};
          
          remoteData.result = this.clicked_list;
          remoteData.key = this.chartOption.sameRemoteKey;

          remoteTabApi(remoteData);

        }
        //alert("OvO");
        let c_clicked_list = this.clicked_list;

        if(this.chartOption.checkType == 'single'){
            //单选
            this.clicked_list.splice(0, 1);
            this.clicked_list.push(index);
            
        }else{
            //如果点击块数大于或等于最大点击块数 && 点击的色块未变色: 直接返回
            if (c_clicked_list.length >= this.max_clicked && (c_clicked_list.indexOf(index) == -1)){
                return
            }
            var listIdx = c_clicked_list.indexOf(index);
            if (listIdx > -1) {
                this.clicked_list.splice(listIdx, 1);
            } else {
                this.clicked_list.push(index);
            }
           
        }
            
        // 0. 获取当前绑定组件id
        //console.log(">3<", this.chartOption.selectedCharts);
        
        this.$nextTick(() => {
            // 1. 创建请求参数的字符串
            let arr = [];
            let slectedList = document.getElementsByName("onSelected")
            //console.log('slectedList', slectedList);
            if(slectedList.length == 0 ) { 
              
              // alert("无选中的标签，请选择标签。"); 
              return ;
            } else { 
                
                for (let index of c_clicked_list) {
                   
                    arr.push(this.boxes[index].key);
                    //.log("arr", arr);
                }
                    this.paramStr = arr.join(',');
                    //console.log("=3=", this.paramStr);
            }
        
            // 2. 把参数赋给绑定组件的请求参数
            let bindList = this.chartOption.selectedCharts;
            let name = this.chartOption.name;
            if(bindList.length > 0){
                let exclusion = ["input","timeframe", "select", "cascade","tab","textCheckBox","timeline","group"];
                //console.log("O-O", this.drawingList);
                let renderCharts = this.drawingList.filter(item => { 
                    return bindList.indexOf(item.customId) > -1 && exclusion.indexOf(item.type) == -1
                })
                let that = this;
                
                //遍历绑定组件
                renderCharts.forEach(item => {

                //获取组件参数
                let requestParameters = item.chartOption.requestParameters;

                //如果已经包含该名称的参数则替换
                if(requestParameters != "" && requestParameters.indexOf(name) != -1){
                    //拆分成数组
                    let paramArr = requestParameters.split('&');
                    if(paramArr.length>1){
                      paramArr.pop();
                    }
                    //获取到包含该名称的数组项
                    for(let i in paramArr){
                    if(paramArr[i].indexOf(name) != -1){
                        //替换位=为当前内容
                        //console.log('你猜我有没有值', that.paramStr)
                        paramArr.splice(i, 1, name + "=" + that.paramStr)
                    
                    }
                    }
                    //将数组重新按照&符号拼接为字符串
                    requestParameters = '&' + paramArr.join("&")
                    
                } else {
                    if(requestParameters != ""){
                      let paramArr = requestParameters.split('&');
                      if(paramArr.length>1){
                        paramArr.pop();
                      }
                      requestParameters = '&' + paramArr.join("&")
                    }
                    //如果为新名称参数直接拼在结尾
                    requestParameters += "&" + this.chartOption.name + "=" + that.paramStr;
                }
                //判断参数是否已&符号开始，是则删除该符号
                if(requestParameters.indexOf('&') == 0){
                    item.chartOption.requestParameters = requestParameters.substring(1, requestParameters.length) + "&timestamp="+new Date().getTime();
                }else{
                    // 3. 给绑定组件重新赋值参数渲染组件
                    item.chartOption.requestParameters = requestParameters + "&timestamp="+new Date().getTime();
                }
                
                });

            }
            //远程控制组件
            if(this.chartOption.isRemote == true){

                if(this.chartOption.remote != undefined && this.chartOption.remote != null){
                  let remoteData = { ...this.chartOption.remote };
                  let queryObj = {};
                  queryObj[this.chartOption.name] = this.paramStr;
                  remoteData.query = queryObj;
                  //调用接口
                  remoteChartApi(remoteData)
                }
            }  
		    } )	

    },

    isClicked(index) {
        return this.clicked_list.indexOf(index) + 1;
    },

    setOptions: async function (dataOption) {
      this.rotationIndex = 0;
      //console.log("==", this.chartOption);
      //初始化数据
      //如果不是静态数据就调用接口给staticDataValue赋值
      if (dataOption.dataSourceType == "url" || dataOption.isStaticData == false) {
        let paramJson = parseQueryString(dataOption.requestParameters);

        let interfaceURL = dataOption.interfaceURL;

        let result = await chartApiBar(
          dataOption.requestMethod,
          interfaceURL,
          paramJson,
          dataOption.token
        );
        dataOption.staticDataValue = result;

      } else if (dataOption.dataSourceType == "database") {
         if (dataOption.database.executeSql != undefined && dataOption.database.executeSql != '') {
          
          let result = [];
          if(dataOption.database.sqlType == 'custom'){
          
            result = await chartBIanalysis(dataOption.database);
          }
          if (result.code == 200) {
            dataOption.staticDataValue = result.data;
            //console.log(dataOption.staticDataValue);
          } else {
            alert("操作数据库错误");
          }
        }       
      } else if (dataOption.dataSourceType == "websocket") {
        if (
          dataOption.interfaceKey != undefined &&
          dataOption.interfaceKey != ""
        ) {
          if (!this.wsFlag) {
            this.wsFlag = true;
            this.wsValue = null;
            this.createWs();
          }
          if (this.wsValue != null) {
            dataOption.staticDataValue = this.wsValue;
          }
        }
      }
      
      if (dataOption.animate != null) {
        //添加动画样式
        //animateUtil.addAnimate(dataOption.bindingDiv, dataOption.animate);
      };
      if(dataOption.isControl == true){
        if (dataOption.controlKey != undefined &&dataOption.controlKey != "") {
          if (!this.controlWsFlag) {
            this.controlWsFlag = true;
            this.controlCreateWs();
          }else{
            this.controlCloseWs();
            this.controlCreateWs();
          }
        }
      }
      this.boxes = dataOption.staticDataValue;
      
      //数据处理
       if(dataOption.customData != undefined && dataOption.customData != ""){
          this.$nextTick(() => {
             try {
               dataOption.staticDataValue = (
                //里面为要处理的代码块 
                eval(dataOption.customData) 
              
              )(
                dataOption.staticDataValue,
                this.$refs.text
              );
              this.boxes = dataOption.staticDataValue;
             } catch (error) {
              console.log(error)
             }
             
          })
       }

      //交互组件配置
       if(dataOption.interactData != undefined && dataOption.interactData != ""){
          this.$nextTick(() => {
             try {
               dataOption.staticDataValue = (
                //里面为要处理的代码块 
                eval(dataOption.interactData) 
              
              )(
                dataOption.staticDataValue,
                this.$refs.text
              );
              this.boxes = dataOption.staticDataValue;
             } catch (error) {
              console.log(error)
             }
             
          })
       }       


      if(this.chartOption.checkType == "single"){
        this.rotationChart();
      }
    },
    rotationChart(){
      //判断是否开启定时器，选择开启轮播并且dur不为0时候开启定时器
      if(this.carouselTimer != '') {
        clearTimeout(this.carouselTimer);
      }
      if(this.chartOption.isRotation == true && this.chartOption.dur > 0 && this.boxes.length > 0) {
       
        let timerTask = () => {
          this.chooseBox(this.rotationIndex);
          this.rotationIndex ++ ;
          if(this.rotationIndex == this.boxes.length){
            this.rotationIndex = 0;
          }
          this.carouselTimer = setTimeout(() => {
            timerTask();
          }, this.chartOption.dur);
        }

        timerTask();
      }
    },
    start(){
      if(this.chartOption.isRotation == true && this.chartOption.dur > 0 && this.boxes.length > 0) {
       
        let timerTask = () => {
          this.chooseBox(this.rotationIndex);
          this.rotationIndex ++ ;
          if(this.rotationIndex == this.boxes.length){
            this.rotationIndex = 0;
          }
          this.carouselTimer = setTimeout(() => {
            timerTask();
          }, this.chartOption.dur);
        }

        timerTask();
      }
    },
    pause(){
      if(this.chartOption.isRotation == true && this.chartOption.dur > 0) {
        clearTimeout(this.carouselTimer);
      }
    },    
    //  ws连接成功，后台返回的ws数据
    controlReceiveMsg(e) {
      if (e.action == "chat") {
        // console.log('服务端推送',e);
        let selectValue = JSON.parse(e.result);
        this.clicked_list = selectValue;
      }
    },
    // 建立连接、发起ws请求，以心跳方式，向服务端发送数据
    controlCreateWs() {
      this.controlWsObj = new WebSocket(process.env.VUE_APP_WEBSOCKET);
      // 若为对象类型，以回调方式发送
      websocketCommand(
        this.controlWsObj,
        "create",
        5000,
        this.chartOption.controlKey,
        this.controlSendHeartBeat,
        this.controlReceiveMsg,
        this.controlReconnectWs,
        this.controlWsWarning
      );
    },
    // 断网重连，需要处理的逻辑
    controlReconnectWs() {
      if (this.controlWsObj) {
        console.log("%c websocket_reconnect", "color:blue");
        this.controlCreateWs();
      }
    },
    // 以回调方式向服务端发送(对象类型的)心跳
    controlSendHeartBeat() {
      if (this.controlWsTimer != "") {
        clearTimeout(this.controlWsTimer);
      }

      let controlWsTimerTask = () => {
        console.log("发送心跳", "ping");
        let obj = { action: "keep", key: this.chartOption.controlKey };
        this.controlWsObj.send(JSON.stringify(obj));
        this.controlWsTimer = setTimeout(() => {
          controlWsTimerTask();
        }, parseInt(process.env.VUE_APP_WEBSOCKET_TIMEOUT));
        this.controlWsWarning();
      };
      controlWsTimerTask();
    },

    controlWsWarning() {
      //如果断开连接则显示组件警告动画并清除计数器
      if (this.controlWsObj.readyState == 3) {
        this.animate = "warning";
        clearTimeout(this.controlWsTimer);
      }
    },
    controlCloseWs() {
      clearTimeout(this.controlWsTimer);
      websocketCommand(
        this.controlWsObj,
        "close",
        5000,
        this.chartOption.controlKey,
        this.controlSendHeartBeat,
        this.controlReceiveMsg,
        this.controlReconnectWs,
        this.controlWsWarning
      );
      this.controlWsObj = null;
    },
    //  ws连接成功，后台返回的ws数据
    receiveMsg(e) {
      if (e.action == "chat") {
        // console.log('服务端推送',e);
        this.wsValue = e.result;
        this.setOptions(JSON.parse(JSON.stringify(this.chartOption)));
      }
    },
    // 建立连接、发起ws请求，以心跳方式，向服务端发送数据
    createWs() {
      this.wsObj = new WebSocket(process.env.VUE_APP_WEBSOCKET);
      // 若为对象类型，以回调方式发送
      websocketCommand(
        this.wsObj,
        "create",
        5000,
        this.chartOption.interfaceKey,
        this.sendHeartBeat,
        this.receiveMsg,
        this.reconnectWs,
        this.wsWarning
      );
    },
    // 断网重连，需要处理的逻辑
    reconnectWs() {
      if (this.wsObj) {
        console.log("%c websocket_reconnect", "color:blue");
        this.createWs();
      }
    },
    // 以回调方式向服务端发送(对象类型的)心跳
    sendHeartBeat() {
      if (this.wsTimer != "") {
        clearTimeout(this.wsTimer);
      }

      let wsTimerTask = () => {
        console.log("发送心跳", "ping");
        let obj = { action: "keep", key: this.chartOption.interfaceKey };
        this.wsObj.send(JSON.stringify(obj));
        this.wsTimer = setTimeout(() => {
          wsTimerTask();
        }, parseInt(process.env.VUE_APP_WEBSOCKET_TIMEOUT));
        this.wsWarning();
      };

      wsTimerTask();
    },
    wsWarning() {
      //如果断开连接则显示组件警告动画并清除计数器
      if (this.wsObj.readyState == 3) {
        this.animate = "warning";
        clearTimeout(this.wsTimer);
      }
    },
    closeWs() {
      clearTimeout(this.wsTimer);
      websocketCommand(
        this.wsObj,
        "close",
        5000,
        this.chartOption.interfaceKey,
        this.sendHeartBeat,
        this.receiveMsg,
        this.reconnectWs,
        this.wsWarning
      );
      this.wsObj = null;
    }
  },
};
</script>
<style ang="scss" scoped>
.chooseCard {
    float: left;
    cursor: pointer;
}

</style>
